from __future__ import annotations

import sys
from dataclasses import dataclass
from enum import Enum
from typing import Any

from archinstall.lib.translationhandler import tr

from ..hardware import SysInfo
from ..output import warn


class Bootloader(Enum):
	NO_BOOTLOADER = 'No bootloader'
	Systemd = 'Systemd-boot'
	Grub = 'Grub'
	Efistub = 'Efistub'
	Limine = 'Limine'

	def has_uki_support(self) -> bool:
		match self:
			case Bootloader.Efistub | Bootloader.Limine | Bootloader.Systemd:
				return True
			case _:
				return False

	def has_removable_support(self) -> bool:
		match self:
			case Bootloader.Grub | Bootloader.Limine:
				return True
			case _:
				return False

	def json(self) -> str:
		return self.value

	@classmethod
	def get_default(cls) -> Bootloader:
		from ..args import arch_config_handler

		if arch_config_handler.args.skip_boot:
			return Bootloader.NO_BOOTLOADER
		elif SysInfo.has_uefi():
			return Bootloader.Systemd
		else:
			return Bootloader.Grub

	@classmethod
	def from_arg(cls, bootloader: str, skip_boot: bool) -> Bootloader:
		# to support old configuration files
		bootloader = bootloader.capitalize()

		bootloader_options = [e.value for e in Bootloader if e != Bootloader.NO_BOOTLOADER or skip_boot is True]

		if bootloader not in bootloader_options:
			values = ', '.join(bootloader_options)
			warn(f'Invalid bootloader value "{bootloader}". Allowed values: {values}')
			sys.exit(1)

		return Bootloader(bootloader)


@dataclass
class BootloaderConfiguration:
	bootloader: Bootloader
	uki: bool = False
	removable: bool = False

	def json(self) -> dict[str, Any]:
		return {'bootloader': self.bootloader.json(), 'uki': self.uki, 'removable': self.removable}

	@classmethod
	def parse_arg(cls, config: dict[str, Any], skip_boot: bool) -> BootloaderConfiguration:
		bootloader = Bootloader.from_arg(config.get('bootloader', ''), skip_boot)
		uki = config.get('uki', False)
		removable = config.get('removable', False)
		return cls(bootloader=bootloader, uki=uki, removable=removable)

	@classmethod
	def get_default(cls) -> BootloaderConfiguration:
		return cls(bootloader=Bootloader.get_default(), uki=False, removable=False)

	def preview(self) -> str:
		text = f'{tr("Bootloader")}: {self.bootloader.value}'
		text += '\n'
		if SysInfo.has_uefi() and self.bootloader.has_uki_support():
			if self.uki:
				uki_string = tr('Enabled')
			else:
				uki_string = tr('Disabled')
			text += f'UKI: {uki_string}'
			text += '\n'
		if SysInfo.has_uefi() and self.bootloader.has_removable_support():
			if self.removable:
				removable_string = tr('Enabled')
			else:
				removable_string = tr('Disabled')
			text += f'{tr("Removable")}: {removable_string}'
			text += '\n'
		return text
